use std::collections::HashMap;
/**
 * @author Dream-Lab مۇختەرجان مەخمۇت
 * @email ug-project@outlook.com
 * @create date 2022-07-25 01:08:49
 * @modify date 2022-07-25 01:08:49
 * @desc [description]
*/

use std::sync::Arc;
use tonic::{Request, Response, Status};
use crate::DataContainer;
use crate::gen::entities::{Location, MetaData, Rider};
use crate::gen::mini_mulazim::{CreateRiderRequest, Empty, Id, KeysRequest, KeysResponse};
use crate::gen::mini_mulazim::rider_service_server::RiderService;
use crate::service::exts::{Apply, IntoTonicResponse, OptionToResult, ToKeysResponse, ToOption};

use super::exts::GetEntityKey;
use super::structs::GenericEntityIndex;


pub struct RiderServiceImpl {
    pub data: Arc<DataContainer>
}
#[async_trait::async_trait]
impl RiderService for RiderServiceImpl {
    async fn create(&self, request: Request<CreateRiderRequest>) -> Result<Response<Rider>, Status> {
        let request = request.into_inner();
        self.data.get_user_by_id(&request.user_id).into_result(Status::not_found("rider account not found."))?;
        {
            let rider = self.data.insert_rider(Rider {
                meta: MetaData::new_with_default_value().into(),
                user_id: request.user_id,
                user: None,
                work_number: "0x000001".into(),
                current_location: Some(Location {
                    meta: MetaData::new_with_default_value().into(),
                    latitude: 1.234,
                    longitude: 2.345,
                })
            });
            // self.data.insert_data(&self.data.orders_of_rider, GenericEntityIndex{
            //     key: rider.key(),
            //     value: Vec::new(),
            // });
            rider
        }.into_option().into_tonic_response()
    }

    async fn update(&self, request: Request<Rider>) -> Result<Response<Rider>, Status> {
        self.data.update_rider(request.into_inner()).into_option().into_tonic_response()
    }

    async fn get_by_id(&self, request: Request<Id>) -> Result<Response<Rider>, Status> {
        self.data.get_rider_by_id(&request.into_inner().uuid).apply(|me|{
            if let Some(ref mut me) = me {
                me.user = self.data.get_user_by_id(&me.user_id);
            }
        }).into_tonic_response()
    }

    async fn list(&self, request: Request<KeysRequest>) -> Result<Response<KeysResponse>, Status> {
        self.data.get_keys_of(&self.data.riders, &request.into_inner()).into_keys_response().into_option().into_tonic_response()
    }
}
